<template>
  <div class="init-container">
    <div class="mask-container" v-if="isMask"></div>
    <div class="container">
      <Split v-model="splitLeft">
        <template #left>
          <o-tree-grid :config="treeConfig"></o-tree-grid>
        </template>
        <template #right>
          <div class="chart-container">
            <div class="toolbar">
              <DatePicker
                v-model="timeRange"
                type="datetimerange"
                placeholder="选择时间范围"
                @on-ok="handleTimeChange"
                @on-clear="handleTimeChange"
              />
              <Button @click="handlePrint">打印图表</Button>
            </div>
            <div ref="chartRef" class="chart"></div>
            <div class="statistics">
              <div>
                最小值：{{ extremeValues.min.value }}（时间：{{
                  extremeValues.min.time
                }}）
              </div>
              <div>
                最大值：{{ extremeValues.max.value }}（时间：{{
                  extremeValues.max.time
                }}）
              </div>
            </div>
          </div>
        </template>
      </Split>
    </div>
  </div>
</template>

<script lang="ts">
import * as echarts from 'echarts';
import {
  Tsrv,
  T_srv,
  ifs,
  ts,
  vue,
  I_cmd,
  T_cmd,
  N_HistoricalCurve,
  treeConfig
} from './config';

type EChartsOption = echarts.EChartsOption;

@T_srv.comp
export default class cHistoricalCurve extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  /* 组件名 */
  private name: string = 'cHistoricalCurve';

  private funName: string = 'cHistoricalCurve';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  private isMask: boolean = false;

  private splitLeft: number = 0.15;

  private chart: echarts.ECharts | null = null;

  private chartData: N_HistoricalCurve.ChartDataSet = {
    title: '化学除油1号槽温度',
    total: 12,
    code: 'my092',
    conversionRate: 10,
    values: [
      [Date.now(), 0],
      [Date.now() + 3600000, 0]
    ]
  };

  private timeRange: [Date, Date];

  private extremeValues = {
    min: { value: Infinity, time: '' },
    max: { value: -Infinity, time: '' }
  };

  private treeConfig = treeConfig();

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    // this.GT_command.init(this, this.GT_compBoxInfo);
    // this.init();
    this.timeRange = this.getDefaultRange();
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    // this.GT_command.startTask();
    this.$bus.$on(
      this.treeConfig.messageConfig.emitActions.search[0].toID,
      (msg: any) => {
        this.handleListener(msg);
      }
    );
    this.initChart();
    this.handleTimeChange();
  }

  private init() {
    this.initChart();
  }

  private handleListener(msg: any) {
    const custMsg = Tsrv.utils.clone(msg, true);
    const data = custMsg.option.autoCompleteInfo.data;
    if (data['f_name'] === '全部') return;

    const [start, end] = [
      new Date(this.formatDate(this.timeRange[0])).toISOString(),
      new Date(this.formatDate(this.timeRange[1])).toISOString()
    ];
    const code = data['m2o|_da_ecbox_id|_da_ecbox_det|f_code'];

    this.chartData.title = data['f_name'];
    this.chartData.code = code;
    this.chartData.conversionRate = data['conversion_rate'];
    const params: ifs.I_qryDataReq = {
      ecCodes: [code],
      beginTime: start,
      endTime: end,
      pageNo: 1,
      pageSize: 9999
    };

    this.loadData(params);
  }

  // 请求数据
  private loadData(p: ifs.I_qryDataReq) {
    const code = this.chartData.code;
    Tsrv.getQueryData(p).then(res => {
      if (
        typeof res === 'boolean' ||
        Tsrv.noValue(res) ||
        !res[code] ||
        res[code].d.length === 0
      )
        return;

      // 对原始数据进行降采样处理，采样间隔1分钟（60000毫秒）
      const sampledData = this.downsampleData(res[code].d, 60000);

      this.chartData.values = sampledData.map(d => [
        new Date(d.t).getTime(),
        d.v / this.chartData.conversionRate
      ]);

      this.updateChart();

      // 更新最大最小值
      this.calculateExtremes();
    });
  }

  private getDefaultRange(): [Date, Date] {
    const end = new Date();
    const start = new Date(end.getTime() - 600000);
    return [start, end];
  }

  private formatDate(isoString) {
    // 创建一个 Date 对象
    const date = new Date(isoString);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始，所以需要加1，并且用0填充
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');

    // 拼接成所需的格式
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }

  private initChart() {
    if (!this.$refs.chartRef) return;

    this.chart = echarts.init(this.$refs.chartRef as HTMLElement);
    window.addEventListener('resize', this.handleResize);
    this.updateChart();
  }

  private handleResize() {
    if (!this.chart) return;
    this.chart?.resize();
  }

  private updateChart() {
    if (!this.chart) return;
    this.chart.setOption(this.getChartOption());
  }

  private getChartOption(): EChartsOption {
    return {
      title: {
        text: this.chartData.title,
        left: 'center'
      },
      xAxis: {
        type: 'time'
      },
      yAxis: { type: 'value' },
      series: [
        {
          data: this.chartData.values,
          type: 'line',
          markPoint: {
            data: [
              { type: 'min', name: '最小值' },
              { type: 'max', name: '最大值' }
            ]
          }
        }
      ]
    };
  }

  private handleTimeChange() {
    const [start, end] = [
      new Date(this.timeRange[0]).toISOString(),
      new Date(this.timeRange[1]).toISOString()
    ];

    const code = this.chartData.code;

    const params: ifs.I_qryDataReq = {
      ecCodes: [code],
      beginTime: start,
      endTime: end,
      pageNo: 1,
      pageSize: 999
    };

    this.loadData(params);
  }

  // 新增降采样方法
  private downsampleData(data: ifs.I_codeData['d'], interval: number) {
    if (!data || data.length === 0) return [];

    // 按时间排序
    const sortedData = data.sort(
      (a, b) => new Date(a.t).getTime() - new Date(b.t).getTime()
    );

    // 按指定间隔分组
    const grouped = Tsrv.utils.groupBy(sortedData, item => {
      // 将时间戳转换成本地时间
      const date = new Date(item.t).toLocaleString();
      const timestamp = new Date(date).getTime();
      return Math.floor(timestamp / interval) * interval;
    });
    // 处理每组数据
    return Object.values(grouped).map(group => {
      const values = group.map(item => item.v);
      // 保留两位小数
      const avg = Math.round(Tsrv.utils.mean(values) * 100) / 100;

      return {
        t: group[0].t,
        v: avg
      };
    });
  }

  private handlePrint() {
    if (!this.chart) return;
    const chartDataURL = this.chart.getDataURL({ type: 'png' });
    const printWindow = window.open('', '_blank');
    printWindow?.document.write(
      `<img src="${chartDataURL}" style="max-width:100%">`
    );
    printWindow?.print();
  }

  private calculateExtremes() {
    // 最小值
    this.extremeValues.min = this.chartData.values.reduce(
      (acc, cur) => {
        if (cur[1] < acc.value) {
          return { value: cur[1], time: new Date(cur[0]).toLocaleString() };
        }
        return acc;
      },
      { value: Infinity, time: '' }
    );

    // 最大值
    this.extremeValues.max = this.chartData.values.reduce(
      (acc, cur) => {
        if (cur[1] > acc.value) {
          return { value: cur[1], time: new Date(cur[0]).toLocaleString() };
        }
        return acc;
      },
      { value: -Infinity, time: '' }
    );
  }

  destroyed() {
    // 销毁监听事件
    this.$bus.$off(this.treeConfig.messageConfig.emitActions.search[0].toID);
    window.removeEventListener('resize', this.handleResize);
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }
}
</script>

<style lang="scss" scoped>
.container {
  width: 100%;
  height: 100%;
}

.chart-container {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;

  .toolbar {
    padding: 10px;
    display: flex;
    gap: 10px;
  }

  .chart {
    flex: 1;
    width: 75%;
  }

  .statistics {
    padding: 10px;
    border-top: 1px solid #eee;
  }
}
</style>
